<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue';
import { NSelect } from 'naive-ui';
import { InventoryGoods } from '@/service/api/inventory';
import { useAuthStore } from '@/store/modules/auth';
import type {
  BrandOption,
  BrandSelectEmitData,
  GoodsBrandSelectorEmits,
  GoodsBrandSelectorProps,
  RawBrandData
} from './types';

// Props默认值
const props = withDefaults(defineProps<GoodsBrandSelectorProps>(), {
  modelValue: '',
  placeholder: '请选择品牌',
  allowClear: true,
  disabled: false,
  size: 'small',
  showSearch: true,
  filterable: true
});

const emit = defineEmits<GoodsBrandSelectorEmits>();

// 响应式数据
const authStore = useAuthStore();
const brandOptions = ref<BrandOption[]>([]);
const loading = ref(false);
const dataLoaded = ref(false);

// Select组件引用
const selectRef = ref<any>(null);
// 标记是否需要在数据加载完成后自动展开
const shouldAutoOpen = ref(false);

// 双向绑定的选中值
const selectValue = computed({
  get: () => {
    // 确保空值时返回null，这样NSelect才会显示placeholder
    const value = props.modelValue;
    return value === '' || value === null || value === undefined ? null : value;
  },
  set: (value: string | null) => {
    emit('update:modelValue', value || '');
  }
});

// 转换品牌数据为Select格式
const transformBrandData = (brandList: RawBrandData[]): BrandOption[] => {
  if (!Array.isArray(brandList)) return [];

  return brandList.map(item => ({
    label: item.name,
    value: item.objectId,
    objectId: item.objectId,
    name: item.name
  }));
};

// 获取品牌列表
const fetchBrandList = async () => {
  if (loading.value || dataLoaded.value) return;

  loading.value = true;

  // 获取用户权限
  const rights = authStore.getInventoryRights();
  const seeRights = rights?.brand?.see || [];

  const response = await InventoryGoods.getBrandList({
    seeRights
  });

  if (response && !response.error && response.data) {
    let brandData = [];

    // 处理响应数据结构
    if (Array.isArray(response.data)) {
      brandData = response.data;
    } else if (response.data.data && Array.isArray(response.data.data)) {
      brandData = response.data.data;
    }

    // 转换为Select所需的格式
    brandOptions.value = transformBrandData(brandData);
    dataLoaded.value = true;
  } else {
    brandOptions.value = [];
    dataLoaded.value = true;
  }

  loading.value = false;
};

// 获取placeholder文本
const getPlaceholderText = () => {
  // 加载中状态
  if (loading.value) {
    return '正在加载品牌...';
  }
  // 还未加载数据
  if (!dataLoaded.value) {
    return props.placeholder;
  }
  // 已加载但无数据
  if (brandOptions.value.length === 0) {
    return '暂无品牌数据';
  }
  // 已加载有数据
  return props.placeholder;
};

// 事件处理函数
const handleChange = (value: string | null) => {
  const val = value || '';
  emit(
    'change',
    val,
    brandOptions.value.find(item => item.value === val)
  );

  // 兼容原组件的select事件
  if (val) {
    // 有选中值
    const selectedBrand = brandOptions.value.find(brand => brand.value === val);

    const emitData: BrandSelectEmitData = {
      name: selectedBrand?.name || '',
      objectId: val
    };

    emit('select', emitData);
  } else {
    // 清空选择 - 重要：需要通知父组件清空筛选条件
    const emitData: BrandSelectEmitData = {
      name: '',
      objectId: ''
    };

    emit('select', emitData);
  }
};

const handleFocus = () => {
  // 聚焦时加载数据，并标记需要自动展开
  if (!dataLoaded.value && !loading.value) {
    shouldAutoOpen.value = true;
    fetchBrandList();
  }
};

const handleBlur = () => {
  // 可以在这里处理失焦事件
};

// 监听modelValue变化
watch(
  () => props.modelValue,
  () => {
    // 可以在这里处理modelValue变化
  },
  { immediate: true }
);

// 监听品牌选项数据变化，自动展开下拉菜单
watch(
  () => brandOptions.value,
  newOptions => {
    if (shouldAutoOpen.value && newOptions.length > 0) {
      shouldAutoOpen.value = false;

      // 使用nextTick + 延时确保完全渲染后再展开
      nextTick(() => {
        setTimeout(() => {
          // 程序化触发下拉框展开
          if (selectRef.value) {
            selectRef.value.focus?.();
          }
        }, 100);
      });
    }
  },
  { deep: true }
);
</script>

<template>
  <div class="relative">
    <NSelect
      ref="selectRef"
      v-model:value="selectValue"
      :placeholder="getPlaceholderText()"
      :clearable="allowClear"
      :disabled="disabled"
      :filterable="showSearch"
      :loading="loading"
      :options="brandOptions"
      :consistent-menu-width="false"
      :style="{
        width: '120px !important',
        minWidth: '120px !important',
        maxWidth: '120px !important'
      }"
      @update:value="handleChange"
      @focus="handleFocus"
      @blur="handleBlur"
    >
      >
    </NSelect>
  </div>
</template>

<style scoped></style>
